#include "reader.h"

#include "fragment.h"

#include <gio/gio.h>
#include <string.h>

#include <stdio.h>

gboolean 
load_file (gchar * path, GList ** blocks, gboolean read_crc){

	GFile *               file                = NULL;
	GInputStream *        input_stream        = NULL;
	GError *              error               = NULL;
	gchar *               buffer              = NULL;
	gssize                size_read           = 0;	
	gboolean              has_more_fragments  = TRUE;
	gint                  block_number        = 0;
	FILE_FRAGMENT *       file_fragment       = NULL;
	FILE_FRAGMENT_GROUP * file_fragment_group = NULL;
	guint                 iterator            = 0;
	gboolean              successful          = TRUE;

	g_type_init();
	file = g_file_new_for_path (path);

	if (!file)
	{
		g_printf ("\nErro ao carregar o arquivo\n");
		successful = FALSE;
	}
	else
	{
		input_stream = G_INPUT_STREAM(g_file_read (file, NULL, &error));

		if (error)
		{
			g_printf ("%s", error->message);
			g_error_free (error);

			successful = FALSE;
		}
		else
		{
			file_fragment_group = (FILE_FRAGMENT_GROUP *) g_malloc (sizeof (FILE_FRAGMENT_GROUP));
			memset (file_fragment_group, 0, sizeof (FILE_FRAGMENT_GROUP));			

			file_fragment_group->data_list = NULL;

			do
			{
				file_fragment = (FILE_FRAGMENT *) g_malloc (sizeof (FILE_FRAGMENT));								
				memset (file_fragment, 0, sizeof (FILE_FRAGMENT));
				
				file_fragment->data = (gchar *) g_malloc (FRAGMENT_SIZE * sizeof (gchar));

				size_read = g_input_stream_read (input_stream,
								   	file_fragment->data,
								  	FRAGMENT_SIZE,
									NULL,
								   	&error);

				if (read_crc)
				{
					(void) g_input_stream_read (input_stream,
									&(file_fragment->crc16),
									2,
									NULL,
									&error);
				}

				if (error)
				{
					g_printf ("Nao foi possivel ler o bloco: %d", iterator);
					g_error_free (error);
	                        
					has_more_fragments = FALSE;
					successful = FALSE;
				}
				else
				{

					if (size_read < (size_t)FRAGMENT_SIZE){
						has_more_fragments = FALSE;
					}
								
					file_fragment_group->data_list = g_list_append (file_fragment_group->data_list, file_fragment);
				
					if (block_number % 4 == 3)
					{
						*blocks = g_list_append (*blocks, file_fragment_group);
						
						file_fragment_group = (FILE_FRAGMENT_GROUP *) g_malloc (sizeof (FILE_FRAGMENT_GROUP));
						memset (file_fragment_group, 0, sizeof (FILE_FRAGMENT_GROUP));
	
						file_fragment_group->data_list = NULL;
					}

					block_number++;
				}
			}
			while (has_more_fragments);
		}

		g_input_stream_close (G_INPUT_STREAM (input_stream), NULL, &error);

		if (error)
		{
			g_printf ("%s", error->message);
			g_error_free (error);
                
			successful = FALSE;
		}
	}

	return successful;
}
